package lolcodecompiler;

import javax.swing.*;


public class MyLexicalAnalyzer implements LexicalAnalyzer 
{

    int currentPosition = 0;
    String nextChar = "";

    @Override
    public void getNextToken() 
    {
        getCharacter();
        while(isSpace(LOLCodeCompiler.token))
        {
            getCharacter();
        }
        if(LOLCodeCompiler.token.equals("#"))
        {
            processSingleTag();
            while(LOLCodeCompiler.token.endsWith(" "))
            {
                LOLCodeCompiler.token = LOLCodeCompiler.token.substring(0, LOLCodeCompiler.token.length() - 1);
            }
            if(!lookupToken())
            {
                JOptionPane.showMessageDialog(null, "#ERROR invalid token: " + LOLCodeCompiler.token, "#LEXICAL ERROR", JOptionPane.ERROR_MESSAGE);
                System.exit(0);
            }
        }
        else
        {
            processText();
            if(LOLCodeCompiler.token.startsWith(" "))
            {
                LOLCodeCompiler.token = LOLCodeCompiler.token.substring(1, LOLCodeCompiler.token.length());
            }
        }
    }

    @Override
    public void getCharacter() 
    {
        char currentChar =  LOLCodeCompiler.input.charAt(currentPosition);
        LOLCodeCompiler.token = currentChar + "";
        currentPosition++;
    }

    @Override
    public void addCharacter() 
    {
        if((currentPosition + 1) > LOLCodeCompiler.input.length())
        {
            JOptionPane.showMessageDialog(null, "#ERROR invalid token: " + LOLCodeCompiler.token, "#LEXICAL ERROR", JOptionPane.ERROR_MESSAGE);
            System.exit(0);
        }
        char currentChar = LOLCodeCompiler.input.charAt(currentPosition);
        nextChar = currentChar + "";
        currentPosition++;
    }

    @Override
    public boolean isSpace(String sp) 
    {
        return sp.equals(" ") || sp.equals("\t") || sp.equals("\r");
    }
    
     public boolean rest()
    {
        while(LOLCodeCompiler.input.length() > (currentPosition + 1))
        {
            addCharacter();
            if(!isSpace(nextChar))
            {
                return false;
            }
        }
        return true;
    }

    @Override
    public boolean lookupToken() 
    {
        return LOLCodeCompiler.allTags.stream().anyMatch((allTag) -> (LOLCodeCompiler.token.equalsIgnoreCase(allTag.lol)));
    }

    public void processSingleTag()
    {
        addCharacter();
        while(!nextChar.equals("#") && !isSpace(nextChar) && (currentPosition + 1) <= LOLCodeCompiler.input.length())
        {
            LOLCodeCompiler.token += nextChar;
            addCharacter();
        }
        if((currentPosition + 1) >  LOLCodeCompiler.input.length())
        {
            LOLCodeCompiler.token += nextChar;
        }
        else
        {	
            if(nextChar.equals("#"))
            {
                currentPosition--;
            }
            if(!lookupToken())
            {
                 processMultiTag();
            }
            if(!lookupToken())
            {
                 processMultiTag();
            }
        }
    }

    private void processMultiTag()
    {
        LOLCodeCompiler.token += nextChar;
        addCharacter();
        while(!isSpace(nextChar) && !nextChar.equals("#")  && (currentPosition + 1) <= LOLCodeCompiler.input.length())
        {
            LOLCodeCompiler.token += nextChar;
            addCharacter();
        }
        if((currentPosition + 1) >  LOLCodeCompiler.input.length())
        {
                LOLCodeCompiler.token += nextChar;
        }
        else
        {	
            if(nextChar.equals("#"))
            {
                currentPosition--;
            }
        }

    }

    public void processText()
    {
        while(!nextChar.equals("#")  && (currentPosition + 1) <= LOLCodeCompiler.input.length())
        {
            addCharacter();
            if(!nextChar.equals("#"))
            {
                LOLCodeCompiler.token += nextChar;
            }
        }
        if(nextChar.equals("#"))
        {
            currentPosition--;
        }
    }

	
}